#include "log/log.h"
#include "app_message.h"
#include "cJSON/cJSON.h"
#include <stdlib.h>
#include <string.h>


static int hex_tochar(char hex){
    if(hex >= '0' && hex <= '9'){
        return hex - '0';
    }else if(hex >= 'A' && hex <= 'F'){
        return hex - 'A' + 10;
    }else if(hex >= 'a' && hex <= 'f'){
        return hex - 'a' + 10;
    }

}

// "61626364"->abcd
static char * hex_to_str(char *hex_str,int *str_len){

    int hex_len = strlen(hex_str);
    if(hex_len %2 !=0){
        log_error("hex_str len error");
        return NULL;
    }
    *str_len = hex_len /2;
    char *str = (char *)malloc(*str_len);

    for (int i = 0; i < hex_len-1; i+=2){
        int hig_val = hex_tochar(hex_str[i]);
        int low_val = hex_tochar(hex_str[i+1]);
        str[i/2] = (hig_val << 4) | low_val;
    }

    str[*str_len] = '\0';

    return str;

}

static char * str_to_hex(char *str,int str_len){
    char *hex_str = (char *)malloc(str_len*2 + 1);
    for (int i = 0; i < str_len; i++){
 
        sprintf(hex_str + i*2,"%02x",str[i]);
    }
    hex_str[str_len*2] = '\0';

    return hex_str;

}

/** 
 * @brief 根据二进制数据初始化消息
 * @param binary 二进制数据
 * @param len 二进制数据的长度
 * @return Message* 消息结构体指针
*/

Message *app_message_initByBinary(char *binary,int len){
    Message *message = (Message *)malloc(sizeof(Message));
    memcpy(message->conn_type,binary,1);
    memcpy(message->id_len,binary+1,1);
    memcpy(message->msg_len,binary+2,1);
    if (len!= 3 + message->id_len+message->msg_len)
    {
        log_error("binary len error");
        return NULL;
    }
    message->payload = (char *)malloc(message->id_len + message->msg_len);
    memcpy(message->payload,binary+3,message->id_len + message->msg_len);

    return message;
    
}

/** 
 * @brief 根据JSON数据初始化消息
 * @param json JSON数据
 * @param len JSON数据的长度
 * @return Message* 消息结构体指针
*/
Message *app_message_initByJSON(char *json){
    //初始化message空间
    Message *message = (Message *)malloc(sizeof(Message));
    //解析json得到conn_type,id_hex msg_hex
    cJSON *root = cJSON_Parse(json);
    if (root == NULL){
        log_error("json parse error");
        return NULL;
    }
    cJSON *type_obj = cJSON_GetObjectItem(root,"conn_type");
    cJSON *id_obj = cJSON_GetObjectItem(root,"id");
    cJSON *msg_obj = cJSON_GetObjectItem(root,"msg");
    //判断数据是否为空
    if (type_obj == NULL || id_obj == NULL || msg_obj == NULL){
        log_error("json parse error");
        return NULL;
    }
    int conn_type = type_obj->valueint;
    char *id_hex = id_obj->valuestring;
    char *msg_hex = msg_obj->valuestring;
    //将conn——type给message-》conn——type
    message->conn_type = conn_type;

    //需要作特殊处理
    char *id = hex_to_str(id_hex,&message->id_len);
    char *msg = hex_to_str(msg_hex,&message->msg_len);

    message->payload = (char *)malloc(message->id_len + message->msg_len);
    memcpy(message->payload,id,message->id_len);
    memcpy(message->payload+message->id_len,msg,message->msg_len);


    cJSON_Delete(root);

    free(id);
    free(msg);
    
    return message;
}

/** 
 * @brief 将消息转换二进制数据
 * @param message 消息结构体指针
 * @param binary 接受二进制数据的指针
 * @param len 二进制数据的长度
 * @return int 返回转换后的二进制数据的长度
*/

int app_message_toBinary(Message *message,char *binary,int len){

    if (len < 3 + message->id_len + message->msg_len)
    {
        log_error("binary len error");
        return -1;
    }

    // 将message中的数据复制到binary中
    memcpy(binary,&message->conn_type,1);
    memcpy(binary+1,&message->id_len,1);
    memcpy(binary+2,&message->msg_len,1);
    memcpy(binary+3,message->payload,message->id_len + message->msg_len);

    return 3 + message->id_len + message->msg_len;
    
}

/** 
 * @brief 将消息转换JSON数据
 * @param message 消息结构体指针
 * @param json 接受JSON数据的指针
 * @param len JSON数据的长度
 * @return int 返回转换后的JSON数据的长度
*/

int app_message_toJSON(Message *message,char *json,int len){

    cJSON * root = cJSON_CreateObject();
    //将message中的conn_type添加到json对象中
    cJSON_AddNumberToObject(root,"conn_type",message->conn_type);

    char *id_hex = str_to_hex(message->payload,message->id_len);
    cJSON_AddStringToObject(root,"id",id_hex);
    char *msg_hex = str_to_hex(message->payload+message->id_len,message->msg_len);
    cJSON_AddStringToObject(root,"msg",msg_hex);

    char *json_str = cJSON_PrintUnformatted(root);
    if (len < strlen(json_str)+1)
    {
        log_error("json len error");
        return -1;
    }

    strcpy(json,json_str);
    cJSON_Delete(root);
    free(id_hex);
    free(msg_hex);

    return strlen(json_str);
    
}



/** 
 * @brief 将消息释放
 * @param message 消息结构体指针
 * @return void
*/

void app_message_free(Message *message){

    if(message->payload != NULL){
        free(message->payload);
    }

    free(message);
}
